/*
 * Copyright (C) 2010, Funcom AS, All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  @authors
 *  Svein Gunnar Larsen <sveingunnarlarsen@gmail.com>
 *  Erik Thune Lund <culex.eriklund@gmail.com>
 *  Michel Krohn-Dale <kronicz@gmail.com>
 */

package com.funcom.peeler.tool;

import com.funcom.peeler.UpdateCont;
import com.funcom.peeler.WorkBench;
import com.funcom.peeler.action.Place;
import com.funcom.peeler.peelable.PeelComponent;
import com.funcom.peeler.peelable.PeelContainer;
import com.funcom.peeler.peelable.PeelWorkSpace;
import com.funcom.peeler.symbol.Symbol;

import java.awt.event.MouseEvent;

/**
 * Places a component( decided by the ToolPanel ) into the workspace
 * at the clicked location in the nearest container beneath the mouse
 * cursor. Will create the component by default with a size of 100 x 100
 * and place it with the lower left corner on the mouse cursor.
 *
 * Right clicking when this tool is active will change the current tool
 * to the MultiTool for an easy place -> right-click -> move/resize workflow.
 */
public class PlaceTool extends Tool {
    
    public PlaceTool( WorkBench workbench ) {
        super( workbench );
    }

    /**
     * Does the actual placing of the component in the workspace,
     * compensates for coords in the container that the component
     * is placed in. Also takes care of registering the new component
     * in the appropriate places( history, component list ).
     * @param e the MouseEvent that triggers the placing
     */
    public void mousePressed( final MouseEvent e ) {

        // Cancel the placing of components and switch to the MultiTool
        if(e.getButton() == MouseEvent.BUTTON3){
            UpdateCont.get().getToolbox().setTool( Symbol.ToolType.MULTI );
        }

        // Don't do anything on other mouse clicks
        if ( e.getButton() != MouseEvent.BUTTON1 ) return;

        bui.execute( new WorkBench.Task() {

            public void run() {

                if ( UpdateCont.get().newComponentReady() ) {

                    // Find out where the mouse clicked and get the container to
                    // to the place the component in
                    PeelComponent hit_component = bui.getHitComponent( e );
                    PeelContainer new_parent;
                    if ( hit_component instanceof PeelContainer ) {
                        new_parent = (PeelContainer)hit_component;
                    }
                    else {
                        new_parent = hit_component.getParent();
                    }

                    // Calculate the coords to place the component in starting from workspace coords
                    // and translating from there if necessary
                    int x_loc = e.getX() - bui.getWorkSpace().getComponent().getX();
                    int y_loc = e.getY() - bui.getWorkSpace().getComponent().getY();

                    // Translate coords going up until the workspace is hit
                    for ( PeelContainer tmp = new_parent ; !( tmp instanceof PeelWorkSpace) ; tmp = tmp.getParent() ) {
                        x_loc -= tmp.getComponent().getX();
                        y_loc -= tmp.getComponent().getY();
                    }

                    // Do the actually placing and adding
                    PeelComponent component = UpdateCont.get().getNewComponent();
                    component.getComponent().setSize( 100, 100 );
                    component.getComponent().setLocation(x_loc, y_loc);
                    new_parent.addChild( component );

                    // Push a change to the WorkBench for undoing, clear the selections
                    // on the WorkBench, select this new component and notify the component
                    // list in the property window that it needs updating
                    Place change = new Place( component, new_parent, bui );
                    workbench.pushChange( change );
                    bui.clearSelections();
                    bui.select( component );
                    UpdateCont.get().newOrDeleteChange(true);
                }
            }
        });
    }
}
